<!DOCTYPE html>
<html>
	<meta charset="utf-8" />

	<head>
		<title>Redux basic example</title>
		<script src="../js/vue.js"></script>
		<script src="../js/redux.js"></script>
	</head>
	<style>
		.border {
			border: 1px solid #666;
		}
		
		.red {
			color: red;
		}
	</style>

	<body>
		<div id="demo" class="border red">
			<p>{{name}}</p>
			<p>{{state.name}}</p>
			<input v-model="state.name" />
			<button @click="Click()">Ok</button>
		</div>

		<div id="demo2" class="border red">
			<p>{{name}}</p>
			<p>{{state.name}}</p>
			<input v-model="state.name" />
			<button @click="Click()">Ok</button>

		</div>
		<p>
			<h1>
什么是Redux？</h1> 对于前端页面，从数据层面来说，无非就是一系列的状态组合。 在传统的前端开发中，尤其是jQuery横行的年代，状态管理相关的理念一直没有什么起色。 自Flux横空出世以来，各种解决方案层出不穷，百花齐放，Redux也是在这种环境下诞生的。 如何描述Redux呢？ 简而言之，它就是一个状态容器，里面存储了整个应用的所有状态。 Redux的核心思想就是要提供可预测的状态管理，这对日益膨胀的大型应用来说尤其重要。
			<h1>
预备知识</h1>
			<br/>
			<br/>
			<b>Redux中有三个基本概念非常重要：store / reducer / action。</b>
			<br/> <b>Store</b>顾名思义就是状态容器，Redux使用createStore这个API来创建一个全局的状态容器。这里有一点比较重要的就是： Redux应用只能有一个单一的Store 我们暂时不用深究Redux为何如此设计。
			<br/>
			<br/> <b>Reducer</b>是一个纯函数，它的职责就是用来更新状态容器中的状态，这也是Redux中更新状态的唯一途径。
			<br/>
			<br/> <b>Action</b>是一个普通JavaScript对象，它是把数据从应用传递到状态容器的载体。 将action传递到store中很简单，使用store.dispatch(action)就可以了。 为了区分不同的数据来源，我们一般约定每个action都必须要有一个type字段。 这样我们的reducer函数就能根据这个type字段来决定如何修改状态容器。
		</p>
		<p>
			<b>store.subscribe</b>:不断监听dispatch,有dispatch提交则触发回调
			<br/>
			<b>store.dispatch</b>:提交信息到store,触发对应的action并修改store的状态
			<br/>
			<b>store.getState</b>:获取store的当前状态
		</p>
		<script>
			/**
			 * 状态容器的初始状态
			 * 一般用于同构应用，服务器端返回相关数据
			 */
			var INITIAL_STATE = {
				name: "Oaoafly"
			}
			var reducer = function(state = INITIAL_STATE, action) {
				console.log(state)
				//定义默认的state的值
				if(typeof state === 'undefined') {
					//也可以把初始状态定义在这里
					return;
				}
				/**
				 * reducer函数，用于变更状态容器中的状态
				 * 如果action未知，则原样返回
				 * 永远不要修改state，返回一个全新的state
				 */
				switch(action.type) {
					case 'SETNAME':
						//通过这样可以更方便在原来state基础上修改值
						return Object.assign({}, state, {
							name: "Wscats",
							skill: action.skill
						})
					case 'SETNAME2':
						return {
							name: "Windiest"
						}
					default:
						return state
				}
			}
			var store = Redux.createStore(reducer)
				//后面每次state值变动就监听
				/*store.subscribe(function render() {
					console.log(store.getState())
				})*/
			new Vue({
				el: "#demo",
				data: {
					name: "作用域1",
					state: null
				},
				created: function() {
					var self = this;
					this.unSubscribe = store.subscribe(self.updateState)
					this.state = store.getState()
				},
				methods: {
					Click: function() {
						store.dispatch({
							type: 'SETNAME',
							//传递值到action中，并修改store
							skill: 'javascript'
						})
					},
					updateState: function() {
						this.state = store.getState()
					}
				},
				beforeDestroy() {
					this.unSubscribe()
				}
			})
			new Vue({
				el: "#demo2",
				data: {
					name: "作用域2",
					state: null
				},
				created: function() {
					var self = this;
					this.unSubscribe = store.subscribe(self.updateState)
					this.state = store.getState()
				},
				methods: {
					Click: function() {
						store.dispatch({
							type: 'SETNAME2'
						})
					},
					updateState: function() {
						this.state = store.getState()
					}
				}
			})
		</script>
	</body>

</html>